﻿using ASPApiDemo.IService;
using ASPApiDemo.Repository;
using ASPApiDemo.Service;
using Autofac;
using Autofac.Core;
using Autofac.Extras.DynamicProxy;
using System.Reflection;

namespace ASPApiDemo.Extension
{
    public class AutofacModuleRegister : Autofac.Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            //base.Load(builder);
            var basePath = AppContext.BaseDirectory;
            var serviceDllFile = Path.Combine(basePath, "ASPApiDemo.Service.dll");
            var repositoryDllFile = Path.Combine(basePath, "ASPApiDemo.Repository.dll");
            //注册AOP并挂载到服务层上,注意此项目设计了两者服务，泛型服务和一般服务，都要挂载
            var aopTypes = new List<Type>() { typeof(ServiceAOP) };
            builder.RegisterType<ServiceAOP>();
            //【1】注册泛型仓储
            builder.RegisterGeneric(typeof(BaseRepository<>))
                .As(typeof(IBaseRepository<>))
                .InstancePerLifetimeScope();
            //【2】注册泛型服务
            builder.RegisterGeneric(typeof(BaseService<,>))
                .As(typeof(IBaseService<,>))
                .InstancePerLifetimeScope()
                .EnableInterfaceInterceptors()
                .InterceptedBy(aopTypes.ToArray());
            //【3】注册普通服务
            //获取service.dll程序集的所有服务，并注册
            //EndsWith("Service")扫描所有以"Service" 结尾的类,忽略掉接口
            //PropertiesAutowired()启用属性自动注入，泛型服务、集合注入需要指定此属性
            //InstancePerLifetimeScope()使用scope请求是单例，scope之外是瞬时,多个scope也是不同的
            //asp.net core每次http都会自动创建scope
            //AsImplementedInterfaces()自动将类型注册为它所实现的所有接口
            var serviceAssembly = Assembly.LoadFrom(serviceDllFile);
            builder.RegisterAssemblyTypes(serviceAssembly)
                .Where(t => t.Name.EndsWith("Service"))
                .AsImplementedInterfaces()
                .InstancePerLifetimeScope()
                .PropertiesAutowired()
                .EnableInterfaceInterceptors()
                .InterceptedBy(aopTypes.ToArray());
            //【4】注册普通仓储
            //获取repository.dll程序集的所有仓储，并注册
            var repositoryAssembly = Assembly.LoadFrom(repositoryDllFile);
            builder.RegisterAssemblyTypes(repositoryAssembly)
                .Where(t => t.Name.EndsWith("Repository"))
                .AsImplementedInterfaces()
                .InstancePerLifetimeScope()
                .PropertiesAutowired();
            //InstancePerDependency瞬时生命周期,任何时候每次请求都会创建一个新的实例
            //InstancePerLifetimeScope作用域生命周期，同一个生命周期作用域内scope共享同一个实例
            //SingleInstance单例生命周期,整个应用程序生命周期内只创建一个实例
            // 接口绑定实现
            //builder.RegisterType<MyService>().As<IMyService>();
            // 自注册(直接解析实现类)
            //builder.RegisterType<MyService>();
            // 注册带键的服务
            //builder.RegisterType<ServiceA>().Named<IService>("ServiceA");
            //builder.RegisterType<ServiceB>().Named<IService>("ServiceB");
            // 指定生命周期
            //builder.RegisterType<UserService>().As<IUserService>().InstancePerLifetimeScope();
        }
    }
}
